package be.sc.classicnetwork.controller;

import java.util.Collection;
import java.util.HashSet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;

import be.sc.classicnetwork.model.Car;
import be.sc.classicnetwork.model.Image;
import be.sc.classicnetwork.model.Option;
import be.sc.classicnetwork.service.impl.EmailCarNotficationTask;
import be.sc.classicnetwork.util.PropertiesUtils;

/**
 * Form Controller for cars.
 */
public class CarFormController extends AbstractFormController {

	private String rootUrl;

	/**
	 * @see be.sc.classicnetwork.controller.AbstractFormController#initBinder(javax.servlet.http.HttpServletRequest,
	 *      org.springframework.web.bind.ServletRequestDataBinder)
	 */
	@Override
	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		super.initBinder(request, binder);

		// for the one-to-many form (images)
		Car car = (Car) binder.getTarget();
		int addressesMaxIndex = getMaxIndex(request, "h_images");
		if (addressesMaxIndex > -1) {
			for (int i = car.getImages().size(); i <= addressesMaxIndex; i++) {
				car.addImage(new Image());
			}
		}
	}

	/**
	 * @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
	 */
	@Override
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		String id = ServletRequestUtils.getStringParameter(request, "id", null);
		return (StringUtils.isEmpty(id)) ? new Car() : getServiceLocator()
				.getCarService().findByIdFull(id);
	}

	/**
	 * save.
	 */
	private ModelAndView save(HttpServletRequest request,
			HttpServletResponse response, Car car, BindException errors)
			throws Exception {
		// get images to delete
		String[] i2delete = ServletRequestUtils.getStringParameters(request,
				"2delete");
		Image[] images2delete = new Image[i2delete.length];
		for (int i = 0; i < i2delete.length; i++) {
			images2delete[i] = new Image(i2delete[i]);
		}

		// get selected options
		String[] opts = ServletRequestUtils
				.getStringParameters(request, "opts");
		Collection<Option> options = new HashSet<Option>();
		for (int i = 0; i < opts.length; i++) {
			options.add(new Option(opts[i]));
		}

		// save or update
		getServiceLocator().getCarService().saveOrUpdate(car, images2delete,
				options);

		// show confirmation message
		showMessage(request, "Car successfully saved");
		return showForm(request, errors, getFormView());
	}

	/**
	 * email.
	 */
	private ModelAndView email(HttpServletRequest request,
			HttpServletResponse response, Car car, BindException errors)
			throws Exception {
		// get car from DB
		car = getServiceLocator().getCarService().findById(car.getId());

		// get some application properties
		String from = PropertiesUtils.MAIL_FROM;
		String fromPersonal = PropertiesUtils.MAIL_FROM_PERSONAL;
		String subjectPrefix = PropertiesUtils.MAIL_SUBJECT_PREFIX;

		// start another thread to send the email
		getTaskExecutor().execute(
				new EmailCarNotficationTask(
						getServiceLocator().getCarService(),
						getServiceLocator().getMailService(), car, from,
						fromPersonal, rootUrl, subjectPrefix + " Alert"));

		// show confirmation message
		// show confirmation message
		return new ModelAndView("info", "text", "Notification sent");
	}

	/**
	 * @see org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse, java.lang.Object,
	 *      org.springframework.validation.BindException)
	 */
	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {
		Car car = (Car) command;
		String action = ServletRequestUtils.getRequiredStringParameter(request,
				"action");

		return (action.equals("email")) ? email(request, response, car, errors)
				: save(request, response, car, errors);
	}

	public void setRootUrl(String rootUrl) {
		this.rootUrl = rootUrl;
	}

}
